// https://threejs.org/docs/index.html#examples/zh/geometries/ConvexGeometry
import { 
  Color,
  LineSegments,
  Mesh,
  MeshBasicMaterial,
  Object3D,
  PerspectiveCamera, 
  Scene, SphereGeometry, 
  Vector3, 
  WebGLRenderer, 
  WireframeGeometry 
} from 'three'
import stats from '../../utils/stats'
import dat from 'dat.gui'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import { ConvexBufferGeometry } from 'three/examples/jsm/geometries/ConvexGeometry'

const scene = new Scene()
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)
camera.position.set(-11, 14, 50)
camera.lookAt(0, 0, 0)

let group

const geometry = generatePoints()
const matertial = new MeshBasicMaterial({
  color: 0xff9900,
  transparent: false
})
const shape = new Mesh(geometry, matertial)
group.add(shape)
const wireFrame = new WireframeGeometry(geometry)
const lines = new LineSegments(wireFrame)
group.add(lines)

scene.add(group)

const controls = {
  animate: true,
  color: matertial.color.getStyle(),
  redraw() {
    // 生成新几何体
    let newGeometry = new SphereGeometry(this.radius, this.segments, this.segments)

    ;(group.children[0] as Mesh).geometry.dispose()
    ;(group.children[1] as Mesh).geometry.dispose()

    ;(group.children[0] as Mesh).geometry = newGeometry;
    (group.children[1] as Mesh).geometry = new WireframeGeometry(newGeometry);
  }
}

const gui = new dat.GUI()
gui.add(controls, 'animate')
gui.addColor(controls, 'color').onChange(e => {
  matertial.color.set(new Color(e))
})

const renderer = new WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setClearColor(0x000000)

document.body.appendChild(renderer.domElement)
const trackballControls = new TrackballControls(camera, renderer.domElement)

function render() {
  stats.update()
  trackballControls.update()

  controls.animate && (group.rotation.y += 0.01)

  requestAnimationFrame(render)
  renderer.render(scene, camera)
}

render()

function generatePoints() {
  if (group) scene.remove(group)

  let points = []
  for (let i = 0; i < 20; i++) {
    let x = -15 + Math.round(Math.random() * 30)
    let y = -15 + Math.round(Math.random() * 30)
    let z = -15 + Math.round(Math.random() * 30)

    points.push(new Vector3(x, y, z))
  }

  group = new Object3D()

  const matertial = new MeshBasicMaterial({
    color: 0xff0000,
    transparent: false
  })

  points.forEach(point => {
    let geomItem = new SphereGeometry(0.2)
    let meshItem = new Mesh(geomItem, matertial)
    meshItem.position.copy(point)

    group.add(meshItem)
  })

  scene.add(group)

  const convexGeometry = new ConvexBufferGeometry(points)
  convexGeometry.computeVertexNormals()
  return convexGeometry
}